/*
 * Copyright 2007 The semap project development team.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Created by dulanov at Dec 7, 2007 6:14:48 AM.
 *
 * $Id: SPARQLEndPoint.java 895 2007-12-10 07:25:10Z dulanov $
 */

package net.sf.semap.sandbox.sesame;

import java.io.StringWriter;

import net.sf.semap.sandbox.rio.ntriples.NTriplesWriter;
import net.sf.semap.sandbox.sesame.resultio.sparqltsv.SPARQLResultsTSVWriter;

import org.openrdf.query.QueryLanguage;
import org.restlet.Component;
import org.restlet.Restlet;
import org.restlet.data.MediaType;
import org.restlet.data.Protocol;
import org.restlet.data.Request;
import org.restlet.data.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * TODO HTTP HEAD/GET with the SPARQL URL and Accept, Accept-Language HTTP header parameters supports.
 * TODO HTTP POST with N-Triples US-ASCII/UTF-8 format support only.
 * TODO HTTP DELETE, PUT.
 * TODO HTTP OPTIONS.
 * TODO /dump resource.
 *
 * @author <a href="mailto:dulanov@gmail.com">dulanov</a>
 * @version $Id: SPARQLEndPoint.java 895 2007-12-10 07:25:10Z dulanov $
 */
public class SPARQLEndPoint {

	private static final Logger logger = LoggerFactory.getLogger(SPARQLEndPoint.class);

	public static void main(String[] args) {
	    try {
			final NativeRepository repository = new NativeRepository("./target/sesame2/");
			repository.populateByDefault();

			Component component = new Component();
		    component.getServers().add(Protocol.HTTP, 8888);
		    component.getDefaultHost().attach(new Restlet() {

		    	@Override public void handle(Request request, Response response) {
		            try {
    		    		String sparqlQuery = request.getResourceRef().getQueryAsForm().getFirstValue("sparql");
    		    		String sparqlCommand = sparqlQuery.split("\\W")[0];
    		    		if ("ASK".equalsIgnoreCase(sparqlCommand)) {
    		    			boolean result = repository.evaluateBooleanQuery(QueryLanguage.SPARQL, sparqlQuery);
                            response.setEntity(result ? "yes" : "no", MediaType.TEXT_PLAIN);
    		    		} else if ("SELECT".equalsIgnoreCase(sparqlCommand)) {
    						StringWriter stringWriter = new StringWriter();
    						repository.evaluateTupleQuery(QueryLanguage.SPARQL, sparqlQuery, new SPARQLResultsTSVWriter(stringWriter));
                            response.setEntity(stringWriter.getBuffer().toString(), MediaType.TEXT_PLAIN);
    		    		} else if ("CONSTRUCT".equalsIgnoreCase(sparqlCommand)) {
    						StringWriter stringWriter = new StringWriter();
    						repository.evaluateGraphQuery(QueryLanguage.SPARQL, sparqlQuery, new NTriplesWriter(stringWriter));
                            response.setEntity(stringWriter.getBuffer().toString(), MediaType.TEXT_PLAIN);
    		    		} else {
    		    			throw new IllegalArgumentException("Unknown SPARQL command was received");
    		    		}
		            } catch (Exception e) {
		    			logger.error(e.getMessage(), e);
		            }
		        }
		    });
	        component.start();
        } catch (Exception e) {
			logger.error(e.getMessage(), e);
        }
    }
}
